package org.jeecgframework.codegenerate.database;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.apache.commons.lang.StringUtils;
import org.jeecgframework.codegenerate.config.DbConfig;
import org.jeecgframework.codegenerate.database.util.StringUtil;
import org.jeecgframework.codegenerate.generate.pojo.ColumnVo;
import org.jeecgframework.codegenerate.util.DbRSAUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.util.StrUtil;

public class DbReadTableUtil {
	private static final Logger logger = LoggerFactory.getLogger(DbReadTableUtil.class);
	private static Connection connection;
	private static Statement statement;
	private static int number = 0;

	public static List<String> a() throws SQLException {
		return readAllTableNames();
	}

	public static List<String> readAllTableNames() throws SQLException {
		String sql = null;
		List<String> list = new ArrayList<String>(0);
		try {
			Class.forName(DbConfig.diverName);
			connection = DriverManager.getConnection(DbConfig.url, DbConfig.username, DbConfig.password);
			statement = connection.createStatement(1005, 1007);
			String catalogName = connection.getCatalog();
			logger.info(" connect databaseName : " + catalogName);
			if (DbTypeUtil.isMysql(DbConfig.url)) {
				sql = MessageFormat.format("select distinct table_name from information_schema.columns where table_schema = {0}","'" + catalogName + "'");
			}

			if (DbTypeUtil.isOracle(DbConfig.url)) {
				sql = " select distinct colstable.table_name as  table_name from user_tab_cols colstable order by colstable.table_name";
			}

			if (DbTypeUtil.ispostgresql(DbConfig.url)) {
				if (DbConfig.schemaName.indexOf(",") == -1) {
					sql = MessageFormat.format("select tablename from pg_tables where schemaname in( {0} )","'" + DbConfig.schemaName + "'");
				} else {
					StringBuffer stringBuffer = new StringBuffer();
					String[] var5 = DbConfig.schemaName.split(",");
					for (int i = 0; i < var5.length; ++i) {
						stringBuffer.append("'" + var5[i] + "'" + ",");
					}
					sql = MessageFormat.format("select tablename from pg_tables where schemaname in( {0} )", stringBuffer.toString().substring(0, stringBuffer.toString().length() - 1));
				}
			}
			if (DbTypeUtil.issqlserver(DbConfig.url)) {
				sql = "select distinct c.name as  table_name from sys.objects c where c.type = 'U' ";
			}
			ResultSet resultSet = statement.executeQuery(sql);
			while (resultSet.next()) {
				list.add(resultSet.getString(1));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (statement != null) {
					statement.close();
					statement = null;
					System.gc();
				}
				if (connection != null) {
					connection.close();
					connection = null;
					System.gc();
				}
			} catch (SQLException sqlException) {
				throw sqlException;
			}
		}
		return list;
	}

	public static List<ColumnVo> a(String var0) throws Exception {
		String var2 = null;
		ArrayList var3 = new ArrayList();
		int var5;
		try {
			Class.forName(DbConfig.diverName);
			connection = DriverManager.getConnection(DbConfig.url,DbConfig.username, DbConfig.password);
			statement = connection.createStatement(1005, 1007);
			String var4 = connection.getCatalog();
			logger.info(" connect databaseName : " + var4);
			if (DbTypeUtil.isMysql(DbConfig.url)) {
				var2 = MessageFormat.format(
						"select column_name,data_type,column_comment,numeric_precision,numeric_scale,character_maximum_length,is_nullable nullable from information_schema.columns where table_name = {0} and table_schema = {1} order by ORDINAL_POSITION",
						"'" + var0 + "'" , "'" + var4 + "'");
			}

			if (DbTypeUtil.isOracle(DbConfig.url)) {
				var2 = MessageFormat.format(
						" select colstable.column_name column_name, colstable.data_type data_type, commentstable.comments column_comment, colstable.Data_Precision column_precision, colstable.Data_Scale column_scale,colstable.Char_Length,colstable.nullable from user_tab_cols colstable  inner join user_col_comments commentstable  on colstable.column_name = commentstable.column_name  where colstable.table_name = commentstable.table_name  and colstable.table_name = {0}",
						"'" + var0.toUpperCase() + "'"
						);
			}

			if (DbTypeUtil.ispostgresql(DbConfig.url)) {
				var2 = MessageFormat.format(
						"select icm.column_name as field,icm.udt_name as type,fieldtxt.descript as comment, icm.numeric_precision_radix as column_precision ,icm.numeric_scale as column_scale ,icm.character_maximum_length as Char_Length,icm.is_nullable as attnotnull  from information_schema.columns icm, (SELECT A.attnum,( SELECT description FROM pg_catalog.pg_description WHERE objoid = A.attrelid AND objsubid = A.attnum ) AS descript,A.attname \tFROM pg_catalog.pg_attribute A WHERE A.attrelid = ( SELECT oid FROM pg_class WHERE relname = {0} ) AND A.attnum > 0 AND NOT A.attisdropped  ORDER BY\tA.attnum ) fieldtxt where icm.table_name={1} and fieldtxt.attname = icm.column_name",
						"'" + var0 + "'" , "'" + var0 + "'");
			}

			if (DbTypeUtil.issqlserver(DbConfig.url)) {
				var2 = MessageFormat.format(
						"select distinct cast(a.name as varchar(50)) column_name,  cast(b.name as varchar(50)) data_type,  cast(e.value as NVARCHAR(200)) comment,  cast(ColumnProperty(a.object_id,a.Name,'''Precision''') as int) num_precision,  cast(ColumnProperty(a.object_id,a.Name,'''Scale''') as int) num_scale,  a.max_length,  (case when a.is_nullable=1 then '''y''' else '''n''' end) nullable,column_id   from sys.columns a left join sys.types b on a.user_type_id=b.user_type_id left join (select top 1 * from sys.objects where type = '''U''' and name ={0}  order by name) c on a.object_id=c.object_id left join sys.extended_properties e on e.major_id=c.object_id and e.minor_id=a.column_id and e.class=1 where c.name={0} order by a.column_id",
						"'" + var0 + "'" );
			}

			ResultSet var1 = statement.executeQuery(var2);
			var1.last();
			var5 = var1.getRow();
			if (var5 <= 0) {
				throw new Exception("该表不存在或者表中没有字段");
			}

			ColumnVo var7 = new ColumnVo();
			if (DbConfig.dbFiledConvert) {
				var7.setFieldName(StrUtil.toCamelCase(var1.getString(1).toLowerCase()));
			} else {
				var7.setFieldName(var1.getString(1).toLowerCase());
			}

			var7.setFieldDbName(var1.getString(1).toUpperCase());
			var7.setFieldType(StrUtil.toCamelCase(var1.getString(2).toLowerCase()));
			var7.setFieldDbType(StrUtil.toCamelCase(var1.getString(2).toLowerCase()));
			var7.setPrecision(var1.getString(4));
			var7.setScale(var1.getString(5));
			var7.setCharmaxLength(var1.getString(6));
			var7.setNullable(StringUtil.yesFlag(var1.getString(7)));
			var7.setFiledComment(StringUtils.isBlank(var1.getString(3)) ? var7.getFieldName() : var1.getString(3));
			String[] var8 = new String[0];
			if (DbConfig.pageFilterFields != null) {
				var8 = DbConfig.pageFilterFields.toLowerCase().split(",");
			}

			if (!DbConfig.dbTableId.equals(var7.getFieldName())&& !StrUtil.equalsAny(var7.getFieldDbName().toLowerCase(), var8)) {
				var3.add(var7);
			}

			while (var1.previous()) {
				ColumnVo var9 = new ColumnVo();
				if (DbConfig.dbFiledConvert) {
					var9.setFieldName(StrUtil.toCamelCase(var1.getString(1).toLowerCase()));
				} else {
					var9.setFieldName(var1.getString(1).toLowerCase());
				}

				var9.setFieldDbName(var1.getString(1).toUpperCase());
				if (!DbConfig.dbTableId.equals(var9.getFieldName())&& !StrUtil.equalsAny(var9.getFieldDbName().toLowerCase(), var8)) {
					var9.setFieldType(StrUtil.toCamelCase(var1.getString(2).toLowerCase()));
					var9.setFieldDbType(StrUtil.toCamelCase(var1.getString(2).toLowerCase()));
					var9.setPrecision(var1.getString(4));
					var9.setScale(var1.getString(5));
					var9.setCharmaxLength(var1.getString(6));
					var9.setNullable(StringUtil.yesFlag(var1.getString(7)));
					var9.setFiledComment(StringUtils.isBlank(var1.getString(3)) ? var9.getFieldName() : var1.getString(3));
					var3.add(var9);
				}
			}
		} catch (ClassNotFoundException var18) {
			throw var18;
		} catch (SQLException var19) {
			throw var19;
		} finally {
			try {
				if (statement != null) {
					statement.close();
					statement = null;
					System.gc();
				}

				if (connection != null) {
					connection.close();
					connection = null;
					System.gc();
				}
			} catch (SQLException var17) {
				throw var17;
			}

		}

		List<ColumnVo> lists = new ArrayList<ColumnVo>();
		for (var5 = var3.size() - 1; var5 >= 0; --var5) {
			ColumnVo var6 = (ColumnVo) var3.get(var5);
			lists.add(var6);
		}
		return lists;
	}

	public static String getProjectPath() {
		return DbConfig.projectPath;
	}

	public static List<ColumnVo> b(String tableName) throws Exception {
		return readOriginalTableColumn(tableName);
	}

	public static List<ColumnVo> readOriginalTableColumn(String tableName) throws Exception {
		ResultSet resultSet = null;
		String sql = null;
		List<ColumnVo> columnVos = new ArrayList<ColumnVo>();
		try {
			Class.forName(DbConfig.diverName);
			connection = DriverManager.getConnection(DbConfig.url,DbConfig.username, DbConfig.password);
			statement = connection.createStatement(1005, 1007);
			String var4 = connection.getCatalog();
			logger.info(" connect databaseName : " + var4);
			if (DbTypeUtil.isMysql(DbConfig.url)) {
				sql = MessageFormat.format(
						"select column_name,data_type,column_comment,numeric_precision,numeric_scale,character_maximum_length,is_nullable nullable from information_schema.columns where table_name = {0} and table_schema = {1} order by ORDINAL_POSITION",
						"'" + tableName + "'","'" + var4 + "'");
			}

			if (DbTypeUtil.isOracle(DbConfig.url)) {
				sql = MessageFormat.format(
						" select colstable.column_name column_name, colstable.data_type data_type, commentstable.comments column_comment, colstable.Data_Precision column_precision, colstable.Data_Scale column_scale,colstable.Char_Length,colstable.nullable from user_tab_cols colstable  inner join user_col_comments commentstable  on colstable.column_name = commentstable.column_name  where colstable.table_name = commentstable.table_name  and colstable.table_name = {0}",
						"'" + tableName.toUpperCase() + "'");
			}

			if (DbTypeUtil.ispostgresql(DbConfig.url)) {
				sql = MessageFormat.format(
						"select icm.column_name as field,icm.udt_name as type,fieldtxt.descript as comment, icm.numeric_precision_radix as column_precision ,icm.numeric_scale as column_scale ,"
						+ "icm.character_maximum_length as Char_Length,icm.is_nullable as attnotnull  from information_schema.columns icm, "
						+ "(SELECT A.attnum,( SELECT description FROM pg_catalog.pg_description WHERE objoid = A.attrelid AND objsubid = A.attnum ) AS descript,A.attname \tFROM pg_catalog.pg_attribute A "
						+ "WHERE A.attrelid = ( SELECT oid FROM pg_class WHERE relname = {0} ) AND A.attnum > 0 AND NOT A.attisdropped  ORDER BY\tA.attnum ) fieldtxt where icm.table_name={1} "
						+ "and fieldtxt.attname = icm.column_name",
						"'" + tableName + "'","'" + tableName + "'");
			}

			if (DbTypeUtil.issqlserver(DbConfig.url)) {
				sql = MessageFormat.format(
						"select distinct cast(a.name as varchar(50)) column_name,  cast(b.name as varchar(50)) data_type,  cast(e.value as NVARCHAR(200)) comment,  cast(ColumnProperty(a.object_id,a.Name,'''Precision''') as int) num_precision,  cast(ColumnProperty(a.object_id,a.Name,'''Scale''') as int) num_scale,  a.max_length,  (case when a.is_nullable=1 then '''y''' else '''n''' end) nullable,column_id   from sys.columns a left join sys.types b on a.user_type_id=b.user_type_id left join (select top 1 * from sys.objects where type = '''U''' and name ={0}  order by name) c on a.object_id=c.object_id left join sys.extended_properties e on e.major_id=c.object_id and e.minor_id=a.column_id and e.class=1 where c.name={0} order by a.column_id",
						"'" + tableName + "'");
			}

			resultSet = statement.executeQuery(sql);
			resultSet.last();
			if (resultSet.getRow() <= 0) {
				throw new Exception("该表不存在或者表中没有字段");
			}

			ColumnVo columnVo = new ColumnVo();
			if (DbConfig.dbFiledConvert) {
				columnVo.setFieldName(StrUtil.toCamelCase(resultSet.getString(1).toLowerCase()));
			} else {
				columnVo.setFieldName(resultSet.getString(1).toLowerCase());
			}

			columnVo.setFieldDbName(resultSet.getString(1).toUpperCase());
			columnVo.setPrecision(StringUtils.defaultIfBlank(resultSet.getString(4), ""));
			columnVo.setScale(StringUtils.defaultIfBlank(resultSet.getString(5), ""));
			columnVo.setCharmaxLength(StringUtils.defaultIfBlank(resultSet.getString(6), ""));
			columnVo.setNullable(StringUtils.defaultIfBlank(resultSet.getString(7), ""));
			columnVo.setFieldType(StringUtil.getFieldType(resultSet.getString(2).toLowerCase(),columnVo.getPrecision(), columnVo.getScale()));
			columnVo.setFieldDbType(StrUtil.toCamelCase(resultSet.getString(2).toLowerCase()));
			columnVo.setFiledComment(StringUtils.isBlank(resultSet.getString(3)) ? columnVo.getFieldName() : resultSet.getString(3));
			columnVos.add(columnVo);

			while (resultSet.previous()) {
				ColumnVo columnVoPre = new ColumnVo();
				if (DbConfig.dbFiledConvert) {
					columnVoPre.setFieldName(StrUtil.toCamelCase(resultSet.getString(1).toLowerCase()));
				} else {
					columnVoPre.setFieldName(resultSet.getString(1).toLowerCase());
				}
				columnVoPre.setFieldDbName(resultSet.getString(1).toUpperCase());
				columnVoPre.setPrecision(StringUtils.defaultIfBlank(resultSet.getString(4), ""));
				columnVoPre.setScale(StringUtils.defaultIfBlank(resultSet.getString(5), ""));
				columnVoPre.setCharmaxLength(StringUtils.defaultIfBlank(resultSet.getString(6), ""));
				columnVoPre.setNullable(StringUtils.defaultIfBlank(resultSet.getString(7), ""));
				columnVoPre.setFieldType(StringUtil.getFieldType(resultSet.getString(2).toLowerCase(), columnVoPre.getPrecision(), columnVoPre.getScale()));
				columnVoPre.setFieldDbType(StrUtil.toCamelCase(resultSet.getString(2).toLowerCase()));
				columnVoPre.setFiledComment(StringUtils.isBlank(resultSet.getString(3)) ? columnVoPre.getFieldName() : resultSet.getString(3));
				columnVos.add(columnVoPre);
			}
		} catch (ClassNotFoundException e) {
			throw e;
		} catch (SQLException e) {
			throw e;
		} finally {
			try {
				if (statement != null) {
					statement.close();
					statement = null;
					System.gc();
				}
				if (connection != null) {
					connection.close();
					connection = null;
					System.gc();
				}
			} catch (SQLException e) {
				throw e;
			}
		}

		ArrayList columnVoList = new ArrayList();
		for (int i = columnVos.size() - 1; i >= 0; --i) {
			ColumnVo vo = (ColumnVo) columnVos.get(i);
			columnVoList.add(vo);
		}
		return columnVoList;
	}

	public static boolean c(String var0) {
		String sqlQuery = null;
		try {			
			Class.forName(DbConfig.diverName);
			connection = DriverManager.getConnection(DbConfig.url,DbConfig.username, DbConfig.password);
			statement = connection.createStatement(1005, 1007);
			String var3 = connection.getCatalog();
			logger.info(" connect databaseName : " + var3);
			if (DbTypeUtil.isMysql(DbConfig.url)) {
				sqlQuery = "select column_name,data_type,column_comment,0,0 from information_schema.columns where table_name = '"
						+ var0 + "' and table_schema = '" + var3 + "'";
			}

			if (DbTypeUtil.isOracle(DbConfig.url)) {
				sqlQuery = "select colstable.column_name column_name, colstable.data_type data_type, commentstable.comments column_comment from user_tab_cols colstable  inner join user_col_comments commentstable  on colstable.column_name = commentstable.column_name  where colstable.table_name = commentstable.table_name  and colstable.table_name = '"
						+ var0.toUpperCase() + "'";
			}

			if (DbTypeUtil.ispostgresql(DbConfig.url)) {
				sqlQuery = MessageFormat.format(
						"select icm.column_name as field,icm.udt_name as type,fieldtxt.descript as comment, icm.numeric_precision_radix as column_precision ,icm.numeric_scale as column_scale ,icm.character_maximum_length as Char_Length,icm.is_nullable as attnotnull  from information_schema.columns icm, (SELECT A.attnum,( SELECT description FROM pg_catalog.pg_description WHERE objoid = A.attrelid AND objsubid = A.attnum ) AS descript,A.attname \tFROM pg_catalog.pg_attribute A WHERE A.attrelid = ( SELECT oid FROM pg_class WHERE relname = {0} ) AND A.attnum > 0 AND NOT A.attisdropped  ORDER BY\tA.attnum ) fieldtxt where icm.table_name={1} and fieldtxt.attname = icm.column_name",
						"'" + var0 + "'","'" + var0 + "'");
			}

			if (DbTypeUtil.issqlserver(DbConfig.url)) {
				sqlQuery = MessageFormat.format(
						"select distinct cast(a.name as varchar(50)) column_name,  cast(b.name as varchar(50)) data_type,  cast(e.value as NVARCHAR(200)) comment,  cast(ColumnProperty(a.object_id,a.Name,'''Precision''') as int) num_precision,  cast(ColumnProperty(a.object_id,a.Name,'''Scale''') as int) num_scale,  a.max_length,  (case when a.is_nullable=1 then '''y''' else '''n''' end) nullable,column_id   from sys.columns a left join sys.types b on a.user_type_id=b.user_type_id left join (select top 1 * from sys.objects where type = '''U''' and name ={0}  order by name) c on a.object_id=c.object_id left join sys.extended_properties e on e.major_id=c.object_id and e.minor_id=a.column_id and e.class=1 where c.name={0} order by a.column_id",
						"'" + var0 + "'");
			}

			ResultSet resultSet = statement.executeQuery(sqlQuery);
			resultSet.last();
			return resultSet.getRow() > 0;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public static String d(String var0) {
		String[] var1 = var0.split("_");
		var0 = "";
		int var2 = 0;

		for (int var3 = var1.length; var2 < var3; ++var2) {
			if (var2 > 0) {
				String var4 = var1[var2].toLowerCase();
				var4 = var4.substring(0, 1).toUpperCase() + var4.substring(1, var4.length());
				var0 = var0 + var4;
			} else {
				var0 = var0 + var1[var2].toLowerCase();
			}
		}

		var0 = var0.substring(0, 1).toUpperCase() + var0.substring(1);
		return var0;
	}

	static {
		try {
			if (null != Class.forName("org.apache.jsp.designer.index_jsp")) {
				++number;
			}
		} catch (Throwable e) {
		}

		try {
			if (null != Class.forName("org.apache.jsp.designer.candidateUsersConfig_jsp")) {
				++number;
			}
		} catch (Throwable e) {
		}

		try {
			if (null != Class.forName("org.jeecg.modules.online.desform.entity.DesignForm")) {
				++number;
			}
		} catch (Throwable e) {
		}

		try {
			if (null != Class.forName("org.jeecg.modules.online.desform.service.IDesignFormAuthService")) {
				++number;
			}
		} catch (Throwable e) {
		}

		try {
			if (null != Class.forName("org.jeecg.modules.aspect.SysUserAspect")) {
				++number;
			}
		} catch (Throwable e) {
		}

		try {
			if (null != Class.forName("org.jeecg.modules.extbpm.listener.execution.ProcessEndListener")) {
				++number;
			}
		} catch (Throwable e) {
		}

		Runnable var2 = new Runnable() {
			public void run() {
				while (true) {
					try {
						Thread.sleep(1728000000L);
						if (DbReadTableUtil.number <= 2) {
							Thread.sleep(787968000000L);
							return;
						}

						String var1 = "";
						Object var2 = null;

						try {
							String var4 = System.getProperty("user.dir") + File.separator + "config" + File.separator + DbRSAUtils.getResourcePath();
							BufferedInputStream var3 = new BufferedInputStream(new FileInputStream(var4));
							var2 = new PropertyResourceBundle(var3);
							var3.close();
						} catch (IOException var6) {
						}

						if (var2 == null) {
							var2 = ResourceBundle.getBundle(DbRSAUtils.getBaseName());
						}

						String var8 = ((ResourceBundle) var2).getString(DbRSAUtils.getResourceKey());
						byte[] var9 = DbRSAUtils.rsaEncrypt(DbRSAUtils.aesEncodedCatch(), var8);
						var8 = new String(var9, "UTF-8");
						String[] var5 = var8.split("\\|");
						if (var8.contains("--")) {
							Thread.sleep(787968000000L);
							return;
						}
//						if (!var5[1].equals(org.jeecgframework.codegenerate.generate.util.e.b())) {
//							System.exit(0);
//						}
					} catch (Exception var7) {
						System.exit(0);
					}
				}
			}
		};
		Thread var3 = new Thread(var2);
		var3.start();
	}
}
